#ifdef RT_USE_OLD_CONN_WRAP

#if !defined CS_PDU_H  && !defined (_NEW_PROTO_TP)
#define CS_PDU_H

#include "RtDefines.h"
#include "RtDebug.h"
#include "RtMessageBlock.h"
#include "RtByteStream.h"

#define CS_PDU_TYPE_NONE		0xF
#define CS_PDU_TYPE_HEAD		0x0
#define CS_PDU_TYPE_CONN_REQ	0x1
#define CS_PDU_TYPE_CONN_RESP	0x2
#define CS_PDU_TYPE_DISCONN		0x3
#define CS_PDU_TYPE_KEEPALIVE	0x4
#define CS_PDU_TYPE_DATA_START	0x5	//Indicate Seq# rewound
#define CS_PDU_TYPE_DATA_NORMAL	0x6
#define CS_PDU_TYPE_RTT			0x7

#define CS_CONN_TYPE_NONE		0xF
#define CS_CONN_TYPE_RLB		0x1
#define CS_CONN_TYPE_PKG		0x2

#define PDU_VERSION				1

class /*RT_API_EXPORT*/ CRtCnPduBase
{
public:
	CRtCnPduBase(BYTE byType = CS_PDU_TYPE_HEAD);
	virtual ~CRtCnPduBase();
	
	virtual void Decode(CRtMessageBlock& mb);	//mb >> m_xx
	virtual void Encode(CRtMessageBlock& mb);	//mb << m_xx

	virtual DWORD GetFixLength();
	static DWORD GetFixLength(BYTE byType, BOOL bNeedACK = TRUE);

	BYTE GetType();
protected:
	BYTE m_byType;
};

class /*RT_API_EXPORT*/ CRtCnPduConnReqResp : public CRtCnPduBase
{
public:
	//byType = CS_PDU_TYPE_CONN_REQ || CS_PDU_TYPE_CONN_RESP
	CRtCnPduConnReqResp(
		DWORD dwACK = 0, 
		WORD wConTag = 0, 
		BYTE byType = CS_PDU_TYPE_CONN_REQ, 
		BYTE byConnType = CS_CONN_TYPE_NONE);
	virtual ~CRtCnPduConnReqResp();

	virtual void Decode (CRtMessageBlock& mb);	//mb >> m_xx
	virtual void Encode (CRtMessageBlock& mb);	//mb << m_xx

	DWORD GetACK();
	WORD GetConTag();
	BYTE GetConnType();
protected:
	DWORD m_dwACK;
	WORD m_wConTag;
	BYTE m_byConnType;
};

//////////////////////////////
//PDUs can be add in SendBuf
//////////////////////////////

//SendBuf items, Base class for Data PDU & KeepAlive PDU
class /*RT_API_EXPORT*/ CRtCnPduSendItem : public CRtCnPduBase
{
public:
	CRtCnPduSendItem(
		BOOL bNeedACK, 
		DWORD dwACK = 0, 
		BYTE byType = CS_PDU_TYPE_DATA_NORMAL, 
		DWORD dwDataLen = 0,
		CRtMessageBlock *pData = NULL);
	virtual ~CRtCnPduSendItem();

	virtual void Decode (CRtMessageBlock& mb);	//mb >> m_xx
	virtual void Encode (CRtMessageBlock& mb);	//mb << m_xx

	void SetACK(DWORD dwACK);
	DWORD GetACK();
	DWORD GetDataLen();
	CRtMessageBlock *GetData();
public:
	void SetSeqStart(DWORD dwSeqStart);
	DWORD GetSeqStart();
	DWORD GetSeqEnd();
	void SetNext(CRtCnPduSendItem *pNextPDU);
	CRtCnPduSendItem* GetNext();

	virtual DWORD GetFixLength();
protected:
	DWORD m_dwACK;
	DWORD m_dwDataLen;
	CRtMessageBlock *m_pmbData;
protected:
	DWORD m_dwSeqStart;	//start sequence of this PDU
	DWORD m_dwSeqEnd;	//end sequence of this PDU

	CRtCnPduSendItem *m_pNextPDU;	//point to next CRtCnPduSendItem obj in the list

	BOOL m_bNeedACK;
};

class /*RT_API_EXPORT*/ CRtCnPduDisconn : public CRtCnPduSendItem
{
public:
	CRtCnPduDisconn(
		WORD wReason = 0, 
		BYTE byType = CS_PDU_TYPE_DISCONN);
	virtual ~CRtCnPduDisconn();

	virtual void Decode (CRtMessageBlock& mb);	//mb >> m_xx
	virtual void Encode (CRtMessageBlock& mb);	//mb << m_xx

	WORD GetReason();
protected:
	WORD m_wReason;
};

class /*RT_API_EXPORT*/ CRtCnPduKeepAlive : public CRtCnPduSendItem
{
public:
	CRtCnPduKeepAlive(DWORD dwACK = 0, BYTE byType = CS_PDU_TYPE_KEEPALIVE);
	virtual ~CRtCnPduKeepAlive();

	virtual void Decode (CRtMessageBlock& mb);	//mb >> m_xx
	virtual void Encode (CRtMessageBlock& mb);	//mb << m_xx
};

class /*RT_API_EXPORT*/ CRtCnPduData : public CRtCnPduSendItem
{
public:
	//byType = CS_PDU_TYPE_DATA_START || CS_PDU_TYPE_DATA_NORMAL
	CRtCnPduData(
		BOOL bNeedACK = TRUE,
		DWORD dwACK = 0, 
		DWORD dwDataLen = 0, 
		BYTE byType = CS_PDU_TYPE_DATA_NORMAL, 
		CRtMessageBlock *pData = NULL);
	virtual ~CRtCnPduData();

	virtual void Decode (CRtMessageBlock& mb);	//mb >> m_xx
	virtual void Encode (CRtMessageBlock& mb);	//mb << m_xx

	void DecodeWithOutData(CRtMessageBlock& mb);//mb >> m_xx, only wanna get true data len
	void EncodeWithOutData(CRtMessageBlock& mb);//mb << m_xx, only wanna put true data len
};

class CRtCnPduRtt : public CRtCnPduBase
{
public:
	CRtCnPduRtt(DWORD inTimestamp = 0);
	virtual ~CRtCnPduRtt();

	virtual void Decode (CRtMessageBlock& mb);
	virtual void Encode (CRtMessageBlock& mb);

	DWORD GetTimestamp() const { return m_timestamp; }

protected:
	DWORD m_timestamp;
};

#endif // CS_PDU_H

#endif // RT_USE_OLD_CONN_WRAP
